#include "tcp_server_test.h"
#include "socket.h"
#include <iostream>
#include <vector>

using namespace el;

TcpServerTest::TcpServerTest()
{
}


TcpServerTest::~TcpServerTest()
{
}

bool el::TcpServerTest::test()
{
	loop_ = loop_thread_.startLoop();

	SocketAddrIn addr(INADDR_LOOPBACK, 900);
	server_ = new TcpServer(loop_, addr);
	server_->setNewConnectionCallback(NewTcpConnectCallback(this, &TcpServerTest::connect));
	server_->setMessageCallback(NewTcpConnectCallback(this, &TcpServerTest::message));
	server_->setCloseCallback(NewTcpConnectCallback(this, &TcpServerTest::close));
	server_->setErrorCallback(TcpErrorCallback(this, &TcpServerTest::error));
	server_->start();

	{
		Socket client(Socket::getTcpSocket());
		int rtn = client.connect(addr);
		assert(rtn != -1);
		client.closeFD();
	}

	std::vector<Socket> client_vec;
	for (size_t i = 0; i < 2000; i++)
	{
		Socket client(Socket::getTcpSocket());
		int rtn = client.connect(addr);
		assert(rtn != -1);
		char buf[1024] = { 0 };
		rtn = ::recv(client.fd(), buf, sizeof(buf), 0);
		if (0 == rtn)
		{
			std::cout << "client recv : server full load" << std::endl;
			client.closeFD();
			continue;
		}
		assert(rtn > 0);
		std::cout << "client recv : " << buf << std::endl;
		char buf_send[] = "hello";
		rtn = ::send(client.fd(), buf_send, sizeof(buf_send), 0);
		assert(rtn == sizeof(buf_send));
		client_vec.push_back(client);
	}

	char broadcast[] = "broadcast";
	server_->broadcast(broadcast, sizeof(broadcast));

	int close_c = 0, read_c = 0;
	for (size_t i = 0; i < client_vec.size(); i++)
	{
		char buf[1024] = { 0 };
		int rtn = ::recv(client_vec[i].fd(), buf, sizeof(buf), 0);
		if (0 == rtn)
		{
			std::cout << close_c << " client recv : disconnect" << std::endl;
			close_c++;
			continue;
		}
		assert(rtn > 0);
		std::cout << read_c << " client recv : " << buf << std::endl;
		read_c++;
		client_vec[i].closeFD();
	}
	assert(read_c == client_vec.size());

	server_->stop();
	Sleep(500);
	server_->release();
	Sleep(100);
	loop_thread_.quit();
	return true;
}

void el::TcpServerTest::connect(TcpConnect * connect)
{
	char buf[1024] = { 0 };
	sprintf(buf, "%d : connect", (int)connect->socket().fd());
	connect->sendData(buf, strlen(buf));
}

void el::TcpServerTest::message(TcpConnect * connect)
{
	int rtn = 0;
	char buf[1024] = { 0 };
	do
	{
		rtn = connect->readData(buf, sizeof(buf));
	} while (0 != rtn);
	std::cout << "connect " << connect->socket().fd() << " recv : " << buf << std::endl;
	//connect->sendData(buffer.read(buffer.ableReadSize()), buffer.ableReadSize());
}

void el::TcpServerTest::close(TcpConnect * connect)
{
	static int i = 0;
	i++;
	std::cout << connect->socket().fd() << " : " << "disconnect, i=" << i << std::endl;
}

void el::TcpServerTest::error(TcpConnect * connect, int err)
{
	std::cout << connect->socket().fd() << " : " << "error" << err << std::endl;
}
